package com.dingding.order.core.cancel.biz.impl;

import java.lang.reflect.InvocationTargetException;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.http.HttpStatus;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.dingding.common.core.base.daox.IBaseDaoX;
import com.dingding.common.core.base.daox.ICriteriaBaseDao;
import com.dingding.common.core.base.dto.AbstractResponse;
import com.dingding.common.core.base.dto.ResponseEntity;
import com.dingding.common.core.beans.special.Userspecialorder;
import com.dingding.common.core.beans.special.UserspecialorderT;
import com.dingding.common.core.model.push.PushModel;
import com.dingding.common.core.push.enums.notice.SpecialNoticeEnum;
import com.dingding.common.core.push.enums.push.SpecialDriverPushEnum;
import com.dingding.common.core.push.factory.request.IPushRequestFactory;
import com.dingding.common.core.push.pushbean.specialdriver.CustomerCancelSpecialOrderPush;
import com.dingding.common.core.push.pushmsg.PushMsg;
import com.dingding.common.core.sms.model.MessageModel;
import com.dingding.common.core.util.DateFormatUtil;
import com.dingding.common.core.util.JSONUtil;
import com.dingding.common.core.util.ToolUtil;
import com.dingding.facade.queue.dto.msg.MessageRequestsDTO;
import com.dingding.facade.queue.dto.push.PushRequestDTO;
import com.dingding.facade.queue.enums.ClientType;
import com.dingding.facade.queue.enums.PushType;
import com.dingding.facade.queue.enums.RoleType;
import com.dingding.facade.queue.facade.IQueueFacade;
import com.dingding.order.code.CancelOrderCodeMsg;
import com.dingding.order.core.cancel.biz.ICancelOrderService;
import com.dingding.order.core.cancel.dao.ISpecialCancelOrderDao;
import com.dingding.order.dto.cancel.special.CancelSpecialOrderNoticeDTO;
import com.dingding.order.dto.cancel.special.PushAutoCancelSpecialOrderDTO;
import com.dingding.order.dto.cancel.special.ReqCancelSpecialOrderDTO;
import com.dingding.order.dto.cancel.special.ResCancelSpecialOrderDTO;
import com.dingding.order.dto.publish.PushData;

/**
 * 
 * @ClassName: SpecialCancelOrderServiceImpl
 * @Description: 专车取消订单Service实现类
 * @author YHQ
 * @date 2016年8月23日 下午3:21:41
 * @since V2.4.0
 * 
 */
@Component("specialCancelOrderService")
public class SpecialCancelOrderServiceImpl extends AbstractResponse<ResCancelSpecialOrderDTO, ReqCancelSpecialOrderDTO>
		implements ICancelOrderService {

	private Logger log = Logger.getLogger(this.getClass());

	@Resource(name = "specialCancelOrderDao")
	private ISpecialCancelOrderDao specialCancelOrderDao;

	@Resource(name = "criteriaBaseDao")
	private ICriteriaBaseDao criteriaBaseDao;

	@Resource(name = "queueService")
	private IQueueFacade queueFacade;

	@Resource(name = "specialDriverPushRequestFactory")
	private IPushRequestFactory specialDriverPushRequestFactory;

	@Resource(name = "baseDaoX")
	private IBaseDaoX baseDaoX;

	/**
	 * 
	 * @Title: cancelOrder
	 * @Description: 专车取消订单
	 * @param requestData
	 *            客户端请求参数
	 * @author YHQ
	 * @return String 返回类型
	 * 
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public String cancelOrder(String requestData) {

		// 取消专车订单响应Bean
		ResponseEntity<ResCancelSpecialOrderDTO> response = new ResponseEntity<ResCancelSpecialOrderDTO>();

		// 将客户端请求JSON转换为请求bean
		ReqCancelSpecialOrderDTO reqCancelSpecialOrderDTO = super.parseRequestJson(requestData);

		// 验证请求参数是否为空
		boolean flag = this.validateParam(response, reqCancelSpecialOrderDTO);

		if (!flag) {
			return super.responseBeanToJson(response);
		}

		// 取消订单操作
		boolean cancelOrder = this.cancelSpecialOrderOperation(response, reqCancelSpecialOrderDTO);

		if (cancelOrder) {

			if (reqCancelSpecialOrderDTO.getCancelType() == 1) {// 乘客取消

				// 通知车主
				this.notifyPushToDriver(reqCancelSpecialOrderDTO.getOid());

			} else if (reqCancelSpecialOrderDTO.getCancelType() == 2) {// 车主取消
				
				// 通知乘客
				this.cancelSpecialOrderNotice(reqCancelSpecialOrderDTO);
			}
		}

		ResCancelSpecialOrderDTO resCancelSpecialOrderDTO = new ResCancelSpecialOrderDTO();

		// 取消订单状态
		resCancelSpecialOrderDTO.setOrderStatus(6);

		response.setCode(HttpStatus.SC_OK);
		response.setResponseBody(resCancelSpecialOrderDTO);

		return super.responseBeanToJson(response);
	}

	/**
	 * 
	 * @Title: cancelSpecialOrderOperation
	 * @Description: 取消专车订单操作
	 * @param response
	 *            取消专车订单响应Bean
	 * @param reqCancelSpecialOrderDTO
	 *            取消专车订单请求Bean
	 * @author YHQ
	 * @since V2.4.0
	 * @return boolean 返回类型
	 * 
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	public boolean cancelSpecialOrderOperation(ResponseEntity<ResCancelSpecialOrderDTO> response,
			ReqCancelSpecialOrderDTO reqCancelSpecialOrderDTO) {
		// 根据用户Id获取专车订单信息
		UserspecialorderT userspecialorderT = specialCancelOrderDao
				.getUserSpecialOrdertInfo(reqCancelSpecialOrderDTO.getOid());

		// 判断该订单是否存在
		if (userspecialorderT == null) {

			response.setCode(HttpStatus.SC_FORBIDDEN);
			response.setErrorMessage(CancelOrderCodeMsg.ORDER_NOT_EXISTS);// 订单不存在
			response.setPromptMessage(CancelOrderCodeMsg.ORDER_NOT_EXISTS);// 订单不存在
			return false;
		}

		// 获取专车正式订单对象
		Userspecialorder userspecialorder = this.getUserSpecialOrder(userspecialorderT);

		// 取消原因
		userspecialorder.setCancelDesc(reqCancelSpecialOrderDTO.getCancelDesc());
		// 取消类型
		userspecialorder.setCancelType(reqCancelSpecialOrderDTO.getCancelType());
		//订单结束时间
		userspecialorder.setEndTime(new Date());
		// 取消时间
		userspecialorder.setCancelTime(new Date());
		// 是否评论
		userspecialorder.setIsComment(1);
		// 订单状态
		userspecialorder.setOrderStatus(6);

		try {

			// 保存待取消订单到正式表
			criteriaBaseDao.save(userspecialorder);

			// 删除临时订单
			criteriaBaseDao.delete(userspecialorderT);

		} catch (Exception e) {
			log.error("取消专车订单时出现异常   类：" + this.getClass() + " cancelSpecialOrderOperation()", e);
			response.setCode(HttpStatus.SC_FORBIDDEN);
			response.setErrorMessage(CancelOrderCodeMsg.CANCEL_ORDER_ERROR);// 取消订单失败
			response.setPromptMessage(CancelOrderCodeMsg.CANCEL_ORDER_ERROR);// 取消订单失败
			return false;
		}

		return true;
	}

	/**
	 * 
	 * @Title: getUserSpecialOrder
	 * @Description: 将专车临时订单内容转到专车正式订单
	 * @param userspecialorderT
	 *            专车临时订单对象
	 * @author YHQ
	 * @since V2.4.0
	 * @return Userspecialorder 返回类型
	 * 
	 */
	public Userspecialorder getUserSpecialOrder(UserspecialorderT userspecialorderT) {

		// 专车订单正式表
		Userspecialorder userspecialorder = new Userspecialorder();

		try {
			BeanUtils.copyProperties(userspecialorder, userspecialorderT);

			return userspecialorder;
		} catch (IllegalAccessException e) {
			log.error("", e);
		} catch (InvocationTargetException e) {
			log.error("", e);
		}

		return null;
	}

	/**
	 * 
	 * @Title: confirmAboardNotice
	 * @Description: 确认上车通知操作
	 * @param reqConfirmAboardDTO
	 *            确认上车客户端请求参数
	 * @author YHQ
	 * @since V2.4.0
	 * @return void 返回类型
	 * 
	 */
	public void cancelSpecialOrderNotice(ReqCancelSpecialOrderDTO reqCancelSpecialOrderDTO) {

		// 取消订单通知DTO
		CancelSpecialOrderNoticeDTO cancelNotice = specialCancelOrderDao
				.getNoticeInfo(reqCancelSpecialOrderDTO.getOid(), reqCancelSpecialOrderDTO.getCancelType());

		if (cancelNotice != null) {

			// 推送消息
			this.confirmAboardPushMessage(cancelNotice);

			// 司机确认上车-通知推送
			this.confirmAboardPushNotice(cancelNotice);
		}

	}

	/**
	 * 
	 * @Title: confirmAboardPushMessage
	 * @Description: 确认上车后推送消息
	 * @param confirmAboardNoticeDTO
	 *            确认上车，客户端请求参数
	 * @author YHQ
	 * @since V2.4.0
	 * @return void 返回类型
	 * 
	 */
	public void confirmAboardPushMessage(CancelSpecialOrderNoticeDTO cancelNotice) {

		// 推送Bean
		PushData pushData = new PushData();

		// 推送序号(时间戳)
		pushData.setRequestNumber(DateFormatUtil.getTimeInMillis().toString());
		// 推送时间
		pushData.setRequestTime(DateFormatUtil.yyyy_MM_dd_HHmmss());
		// 模块
		pushData.setModular("specialBboardPush");
		pushData.setResponseBody(cancelNotice);

		PushRequestDTO pushRequestDTO = new PushRequestDTO();

		// 推送别名
		pushRequestDTO.setAliasId(cancelNotice.getAliasId());
		pushRequestDTO.setAlert("取消订单");

		// 设备类型
		if (cancelNotice.getClientType().equals("Android")) {
			pushRequestDTO.setClientType(ClientType.Android);
		} else if (cancelNotice.getClientType().equals("iOS")) {
			pushRequestDTO.setClientType(ClientType.iOS);
		}

		// 消息推送类型
		pushRequestDTO.setPushType(PushType.alert_msgcontent);

		// 推送类型
		pushRequestDTO.setPushContent(JSONUtil.toJSONString(pushData));

		log.info("订单取消推送内容： " + JSONUtil.toJSONString(pushRequestDTO));
		queueFacade.addPushToQueue(JSONUtil.toJSONString(pushRequestDTO));

	}

	/**
	 * 
	 * @Title: confirmAboardPushNotice
	 * @Description: 确认上车后，通知推送消息
	 * @param confirmAboardNoticeDTO
	 *            确认上车，客户端请求参数
	 * @author YHQ
	 * @since V2.4.0
	 * @return void 返回类型
	 * 
	 */
	public void confirmAboardPushNotice(CancelSpecialOrderNoticeDTO cancelNotice) {

		// 推送Bean
		PushData pushData = new PushData();

		String content = "";

		// 推送序号(时间戳)
		pushData.setRequestNumber(DateFormatUtil.getTimeInMillis().toString());
		// 推送时间
		pushData.setRequestTime(DateFormatUtil.yyyy_MM_dd_HHmmss());
		// 模块
		pushData.setModular("cancelSpecialCarOrderPush");
		// 确认到达推送内容
		pushData.setResponseBody(PushModel.noticeModel(1, content, null));

		PushRequestDTO pushRequestDTO = new PushRequestDTO();

		// 推送别名
		pushRequestDTO.setAliasId(cancelNotice.getAliasId());

		// 设备类型
		if (cancelNotice.getClientType().equals("Android")) {
			pushRequestDTO.setClientType(ClientType.Android);
		} else if (cancelNotice.getClientType().equals("iOS")) {
			pushRequestDTO.setClientType(ClientType.iOS);
		}

		// 消息推送类型
		pushRequestDTO.setPushType(PushType.msgcontent);

		// 推送类型
		pushRequestDTO.setPushContent(JSONUtil.toJSONString(pushData));

		log.info("订单取消通知内容： " + JSONUtil.toJSONString(pushRequestDTO));
		queueFacade.addPushToQueue(JSONUtil.toJSONString(pushRequestDTO));
	}

	/**
	 * 
	 * @Title: autoCancelOrder 
	 * @Description: 专车-自动取消订单
	 * @author SUNZHICHENG  
	 * @date  2016年9月5日 下午4:02:18
	 * @since v2.4.0
	 */
	@Override
	@Transactional(propagation=Propagation.REQUIRED)
	public void autoCancelOrder() {
		// 获取待自动取消订单列表
		List<UserspecialorderT> userspecialorders=specialCancelOrderDao.getSpecialOrderts();
		if (userspecialorders!=null && userspecialorders.size()>0) {
			//遍历操作待取消订单
			for (int i = 0; i < userspecialorders.size(); i++) {
				
				UserspecialorderT userspecialorderT=userspecialorders.get(i);
				
				Userspecialorder specialorder=new Userspecialorder();
				boolean flag = this.cancelSpecialOrderHandle(userspecialorderT,specialorder);
				// 取消订单操作成功，通知用户(发送短信，推送消息)
				if (flag) {
					//获取取消订单的推送信息
					PushAutoCancelSpecialOrderDTO pushAutoCancelSpecialOrderDTO=specialCancelOrderDao.getPushCancelSpecialOrder(specialorder.getPlaceOrderUserId());
					
					if (pushAutoCancelSpecialOrderDTO != null) {
						//设置订单状态为已取消
						pushAutoCancelSpecialOrderDTO.setOrderStatus(6);
						//订单id
						pushAutoCancelSpecialOrderDTO.setOid(specialorder.getSpecialOrderId());
						//发布订单类型(1:顺风车 2:出租车 3:专车4:一口价)
						pushAutoCancelSpecialOrderDTO.setPublishType(3);
						
						
						//发送取消短信通知
						sendCancelOrderMessage(pushAutoCancelSpecialOrderDTO);
						
						//发送通知
						pushCancelOrderMessage(pushAutoCancelSpecialOrderDTO);
						
						//发送-通知推送消息
						pushSpecialNoticeMessage(pushAutoCancelSpecialOrderDTO);
					}
					
				}

			}
		}
		

	}
	
	/**
	 * 
	 * @Title: cancelSpecialOrderOperation 
	 * @Description: 保存待取消订单到正式表 删除临时订单
	 * @param userspecialorderT
	 * @return boolean 
	 * @author SUNZHICHENG  
	 * @date  2016年9月5日 下午5:18:15
	 * @since v2.4.0
	 */
	@Transactional(propagation=Propagation.REQUIRED)
	public boolean cancelSpecialOrderHandle(UserspecialorderT userspecialorderT,Userspecialorder userspecialorder){
		
		
		org.springframework.beans.BeanUtils.copyProperties(userspecialorderT, userspecialorder);
		
		// 取消原因
		userspecialorder.setCancelDesc("订单超时,自动取消");
		// 取消类型
		userspecialorder.setCancelType(3);
		//订单结束时间
		userspecialorder.setEndTime(new Date());
		// 取消时间
		userspecialorder.setCancelTime(new Date());
		// 是否评论
		userspecialorder.setIsComment(1);
		// 订单状态
		userspecialorder.setOrderStatus(6);
		
		try {
			// 保存待取消订单到正式表
			criteriaBaseDao.save(userspecialorder);
			// 删除临时订单
			criteriaBaseDao.delete(userspecialorderT);
		} catch (Exception e) {
			log.error("取消专车订单操作时出现异常   类："+this.getClass()+"cancelSpecialOrderOperation() ", e);
			return false;
		}
	
		return true;
	}
	/**
	 * 
	 * @Title: sendCancelOrderMessage 
	 * @Description: 发送取消订单短信通知
	 * @param pushAutoCancelSpecialOrderDTO
	 * @author SUNZHICHENG  
	 * @date  2016年9月5日 下午7:18:50
	 * @since v2.4.0
	 */
	public void sendCancelOrderMessage(PushAutoCancelSpecialOrderDTO pushAutoCancelSpecialOrderDTO){
		MessageRequestsDTO messageRequestsDTO = new MessageRequestsDTO();
		messageRequestsDTO.setTelPhone(pushAutoCancelSpecialOrderDTO.getTelPhone());
		messageRequestsDTO.setMessageContent(MessageModel.AUTO_CANCEL_ORDER_INFO);
		queueFacade.addMessageToQueue(JSONUtil.toJSONString(messageRequestsDTO));
	}
	
	/**
	 * 取消订单推送消息
	 * @Title: pushCancelOrderMessage 
	 * @param pushAutoCancelSpecialOrderDTO
	 * @author SUNZHICHENG  
	 * @date  2016年9月5日 下午7:25:23
	 * @since v2.4.0
	 */
	public void pushCancelOrderMessage(PushAutoCancelSpecialOrderDTO pushAutoCancelSpecialOrderDTO){
			// 推送Bean
			PushData pushData = new PushData();

			// 推送序号(时间戳)
			pushData.setRequestNumber(DateFormatUtil.getTimeInMillis().toString());
			// 推送时间
			pushData.setRequestTime(DateFormatUtil.yyyy_MM_dd_HHmmss());
			// 模块
			pushData.setModular("cancelSpecialOrderPush");

			// 推送内容
			pushData.setResponseBody(pushAutoCancelSpecialOrderDTO);

			PushRequestDTO pushRequestDTO = new PushRequestDTO();
			pushRequestDTO.setAlert(PushMsg.CANCEL_ORDER);
			pushRequestDTO.setMsgTitle(PushMsg.CANCEL_ORDER);
			pushRequestDTO.setAliasId(pushAutoCancelSpecialOrderDTO.getAliasId());
			pushRequestDTO.setPushContent(JSONUtil.toJSONString(pushData));
			pushRequestDTO.setPushType(PushType.alert_msgcontent);
			pushRequestDTO.setRoleType(RoleType.Passenger);
			
			
			// 设备类型
			if (pushAutoCancelSpecialOrderDTO.getLoginEquipment() == 2) {
				pushRequestDTO.setClientType(ClientType.Android);
			} else if (pushAutoCancelSpecialOrderDTO.getLoginEquipment() == 1) {
				pushRequestDTO.setClientType(ClientType.iOS);
			}

			queueFacade.addPushToQueue(JSONUtil.toJSONString(pushRequestDTO));

	}
	
	/**
	 * 
	 * @Title: pushSpecialNoticeMessage 
	 * @Description: 取消订单-通知推送消息
	 * @param pushAutoCancelSpecialOrderDTO
	 * @author SUNZHICHENG  
	 * @date  2016年9月5日 下午7:31:43
	 * @since v2.4.0
	 */
	public void pushSpecialNoticeMessage(PushAutoCancelSpecialOrderDTO pushAutoCancelSpecialOrderDTO){

		// 推送Bean
		PushData pushData = new PushData();
		
		// 推送序号(时间戳)
		pushData.setRequestNumber(DateFormatUtil.getTimeInMillis().toString());
		// 推送时间
		pushData.setRequestTime(DateFormatUtil.yyyy_MM_dd_HHmmss());
		// 模块
		pushData.setModular("newSpecialNoticePush");
		
		// 推送内容
		pushData.setResponseBody(PushModel.noticeModel(1, MessageModel.AUTO_CANCEL_ORDER_INFO, null));
		
		PushRequestDTO pushRequestDTO = new PushRequestDTO();
		pushRequestDTO.setAlert(PushMsg.CANCEL_ORDER);
		pushRequestDTO.setMsgTitle(PushMsg.CANCEL_ORDER);
		pushRequestDTO.setAliasId(pushAutoCancelSpecialOrderDTO.getAliasId());
		pushRequestDTO.setPushContent(JSONUtil.toJSONString(pushData));
		pushRequestDTO.setPushType(PushType.msgcontent);
		pushRequestDTO.setRoleType(RoleType.Passenger);
		// 设备类型
		if (pushAutoCancelSpecialOrderDTO.getLoginEquipment() == 2) {
			pushRequestDTO.setClientType(ClientType.Android);
		} else if (pushAutoCancelSpecialOrderDTO.getLoginEquipment() == 1) {
			pushRequestDTO.setClientType(ClientType.iOS);
		}
		
		queueFacade.addPushToQueue(JSONUtil.toJSONString(pushRequestDTO));
	}
	
	
	
	
	

	/**
	 * @Description:乘客端取消订单，发送推送消息给车主
	 * @author fengshuonan
	 * @return void
	 * @since 2.4
	 */
	@Transactional(readOnly = true)
	public void notifyPushToDriver(String orderId) {

		Userspecialorder userspecialorder = this.baseDaoX.getById(orderId, Userspecialorder.class);
		
		if(ToolUtil.isBlank(userspecialorder.getGrabOrderUserId())){
			return;
		}
		
		//推送消息
		CustomerCancelSpecialOrderPush orderPush = new CustomerCancelSpecialOrderPush();
		orderPush.setOid(orderId);
		orderPush.setOrderStatus(userspecialorder.getOrderStatus());
		orderPush.setPublishType(userspecialorder.getPublishType());//发单类型  3:专车  4:一口价
		orderPush.setOutTime(DateFormatUtil.getMMddEHHss(userspecialorder.getSetOutTime()));
		String pushData = this.specialDriverPushRequestFactory.createPushRequestString(
				SpecialDriverPushEnum.driverCancelSpecialOrderPush.toString(), userspecialorder.getGrabOrderUserId(),
				orderPush);
		this.queueFacade.addPushToQueue(pushData);
		
		//推送通知
		String noticeData = this.specialDriverPushRequestFactory.createNoticeRequest(
				SpecialNoticeEnum.newsNoticePush.toString(), 
				userspecialorder.getGrabOrderUserId(), PushModel.noticeModel(1, "乘客取消了订单"));
		this.queueFacade.addPushToQueue(noticeData);
		
	}

}
